我使用一個叫 handleAnswerProcess 的函示,去包含會在作答的時候去處理作答相關的工作,但主要三大功能為
if (currentCardState.bottom > timelineElState.top) {
    isShowHint.value = true;
    handleTimelineContainerExtend(true);
} else {
    isShowHint.value = false;
    handleTimelineContainerExtend(false);
}
calcTimelineEventCenterLines 函數主要是用於計算時間軸上每個事件(timeline event)的中心線位置,並根據當前拖曳的卡片(clue card)的位置來更新 overOutlineCount 的值。overOutlineCount 邏輯處理流程
示意圖
const calcTimelineEventCenterLines = (timelineEventsElState, currentCardState) => {
    let timelineEventCenterLines = timelineEventsElState.map((el) => window.scrollY + el.top + el.height / 2);
    overOutlineCount.value = timelineEventCenterLines.reduce((acc, cur) => {
        if (currentCardState.bottom > cur) {
            return acc + 1;
        }
        return acc;
    }, 0);
};
if (gameStatus.currentStep === 1) {
        if (currentCardState.bottom > timelineEventsElState[0].bottom) {
            hintPostionTop.value = `${hintDefaultTop + overOutlineCount.value * (timelineEventHeight + timelineEventMarginTop) + hintHeight + timelineEventMarginTop}px`;
        } else {
            hintPostionTop.value = `${hintDefaultTop}px`;
        }
    }
    if (gameStatus.currentStep === 2) {
        //計算每張 timelineEvent 的中心線,如果超過就移動 hint
        calcTimelineEventsCurrentStyles(hintHeight, timelineEventMarginTop);
        hintPostionTop.value = `${hintDefaultTop + overOutlineCount.value * (timelineEventHeight + timelineEventMarginTop)}px`;
    }
    if (gameStatus.currentStep === 3) {
        //計算每張 timelineEvent 的中心線,如果超過就移動 hint
        hintDefaultTop = -40;
        calcTimelineEventsCurrentStyles(hintHeight, timelineEventMarginTop);
        if (overOutlineCount.value === 0) {
            hintPostionTop.value = `${hintDefaultTop}px`;
        } else {
            hintPostionTop.value = `${hintDefaultTop + overOutlineCount.value * (timelineEventHeight + timelineEventMarginTop)}px`;
        }
    }
    if (gameStatus.currentStep > 3) {
        hintDefaultTop = -40;
        calcTimelineEventsCurrentStyles(hintHeight, timelineEventMarginTop);
        if (overOutlineCount.value === 0) {
            hintPostionTop.value = `${hintDefaultTop}px`;
        } else {
            hintPostionTop.value = `${
                hintDefaultTop + (1 * (hintHeight + timelineEventHeight + timelineEventMarginTop)) / 2 + (overOutlineCount.value - 1) * (timelineEventHeight / 2 + timelineEventMarginTop)
            }px`;
        }
    }
const calcTimelineEventsCurrentStyles = (hintHeight, timelineEventMarginTop) => {
    timelineEventsStyleRaw.value.forEach((element, index) => {
        if (index < overOutlineCount.value) {
            timelineEventsStyleRaw.value[index].transform = `translate(-50%, ${currentTimelinePosition.value[index]?.y - (hintHeight + timelineEventMarginTop)}px)`;
        } else {
            timelineEventsStyleRaw.value[index].transform = `translate(-50%, ${currentTimelinePosition.value[index]?.y}px)`;
        }
    });
};
//因為手機長度的限制,當每一個卡片放進作答位置的時候,會更新卡片的排版
currentTimelinePosition
const handleClueCardTouchOff = async (cardIndex, ev) => {
    // 略 
    if (isShowHint.value) {
        handleUpdateTimelinePosition(gameStatus.currentStep);
    } else {
        //略 
    }
    handleTimelineContainerExtend(false);
    document.removeEventListener('touchmove', handleClueCardMove);
};
抓取每一個步驟預設的排版
const handleUpdateTimelinePosition = (currentStep) => {
    // 更新 timelineEvents 的位置
    const updateTimelineEventsPosition = (currentStep, timelineEvents, timelinePositions) => {
        for (let i = 0; i < currentStep; i++) {
            timelineEvents[i].transform = `translate(-50%, ${timelinePositions[i]?.y}px)`;
        }
    };
    currentTimelinePosition.value = clueDefaultPosition[gameStatus.currentStep - 1];
    //略
};
預設遊戲每一個步驟的排版資料,基本上 x 軸都是在中間位置,只有 y 軸有不同高度
[
    [
        {
            "x": "-50%",
            "y": 150
        }
    ],
    [
        {
            "x": "50%",
            "y": 150
        },
        {
            "x": "50%",
            "y": 260
        }
    ],
    [
        {
            "x": "50%",
            "y": 40
        },
        {
            "x": "50%",
            "y": 150
        },
        {
            "x": "50%",
            "y": 260
        }
    ],
    [
        {
            "x": "50%",
            "y": 40
        },
        {
            "x": "50%",
            "y": 100
        },
        {
            "x": "50%",
            "y": 160
        },
        {
            "x": "50%",
            "y": 220
        },
        {
            "x": "50%",
            "y": 280
        },
        {
            "x": "50%",
            "y": 340
        },
        {
            "x": "50%",
            "y": 400
        },
        {
            "x": "50%",
            "y": 460
        },
        {
            "x": "50%",
            "y": 520
        }
    ],
    [
        {
            "x": "50%",
            "y": 40
        },
        {
            "x": "50%",
            "y": 100
        },
        {
            "x": "50%",
            "y": 160
        },
        {
            "x": "50%",
            "y": 220
        },
        {
            "x": "50%",
            "y": 280
        },
        {
            "x": "50%",
            "y": 340
        },
        {
            "x": "50%",
            "y": 400
        },
        {
            "x": "50%",
            "y": 460
        },
        {
            "x": "50%",
            "y": 520
        }
    ],
    [
        {
            "x": "50%",
            "y": 40
        },
        {
            "x": "50%",
            "y": 100
        },
        {
            "x": "50%",
            "y": 160
        },
        {
            "x": "50%",
            "y": 220
        },
        {
            "x": "50%",
            "y": 280
        },
        {
            "x": "50%",
            "y": 340
        },
        {
            "x": "50%",
            "y": 400
        },
        {
            "x": "50%",
            "y": 460
        },
        {
            "x": "50%",
            "y": 520
        }
    ],
    [
        {
            "x": "50%",
            "y": 40
        },
        {
            "x": "50%",
            "y": 100
        },
        {
            "x": "50%",
            "y": 160
        },
        {
            "x": "50%",
            "y": 220
        },
        {
            "x": "50%",
            "y": 280
        },
        {
            "x": "50%",
            "y": 340
        },
        {
            "x": "50%",
            "y": 400
        },
        {
            "x": "50%",
            "y": 460
        },
        {
            "x": "50%",
            "y": 520
        }
    ],
    [
        {
            "x": "50%",
            "y": 40
        },
        {
            "x": "50%",
            "y": 100
        },
        {
            "x": "50%",
            "y": 160
        },
        {
            "x": "50%",
            "y": 220
        },
        {
            "x": "50%",
            "y": 280
        },
        {
            "x": "50%",
            "y": 340
        },
        {
            "x": "50%",
            "y": 400
        },
        {
            "x": "50%",
            "y": 460
        },
        {
            "x": "50%",
            "y": 520
        }
    ]
]